
/**
 * 描述：异步状态管理
 * 参数1 apiFunc
 *      必须是一个Promise。
 * 参数2 option
 *      manual：是否要手动出发，默认false，初始化时候就会调用一次接口，否则则需要自己手动调用run方法
 *      onSuccess:成功时候的回调，返回获取的数据
 *      onError:失败时候的回调，返回失败信息
 *      loadMoreMod 将以 加载更多 模式运行 将所有请求数据合并数组 .then(e)成功返回的数据必须有为{total:Number,records:[]},不是的自己await时候洗一下.
 * 返回值
 *      普通模式下
 *              let state = {
                        data: null, //返回的数据
                        loading: !manual, //是否正在加载
                        error: null, //错误信息
                        isRefresh: false, //是否正在局部刷新
                        run(params) ,调用接口，params是参数,会直接传给了apiFunc(params)，当然如果你的apifunc不接受参数，那就当然没用了。
                        reFresh() 局部刷新。和run的区别就是，调用的时候不会将data重新置为null，而是在加载成功后替换掉。
                   }
        加载更多模式下
                 let state = {
                        data: null, //返回的数据
                        loading: !manual, //是否正在加载
                        error: null, //错误信息
                        run(params) ,调用接口，params是参数,会直接传给了apiFunc(params)，当然如果你传递apiFunc不接受参数，那就当然没用了。

                        isThereMore:是否还有更多的数据
                        loadingMore:是否正在加载更多中
                        isReloading：是否正在重新加载中，只是为了和loading状态区分开。
                        reLoad():重新加载
                        loadMore():加载更多
                   }
 */
function useRequest(apiFunc, option = {
    manual: false,
    onSuccess: false,
    onError: false,
    loadMoreMod:false,
}) {
    const {manual, onSuccess, onError,loadMoreMod} = option
    //通用状态
    let state = {
        data: null,
        loading: !manual,
        error: null,
        isRefresh: false,
    }
    //如果开启了加载更多模式则添加【是否有更多数据状态】
    if(loadMoreMod){
        state.isThereMore=true
        state.loadingMore=false
        state.isReloading=false
    }

    //保存下查询的参数,列表带参数，调用reload后传递的参数保存下，给下次loadMore时候用。
    let tempParams=""

    const execute = (params,opt={isRefresh:false,isReload:false}) => {
        const {isRefresh,isReload}=opt
        apiFunc(params)
            .then((e) => {
                state.loading = false
                //加载更多模式 合并请求的数据
                if(loadMoreMod){
                    state.loadingMore=false
                    handleLoadMoreModData(e,isReload)
                }
                //普通模式
                else {
                    state.data = e
                    if(isRefresh){
                        state.isRefresh=false
                    }
                }

                //如果是正在reload 关闭状态
                if(isReload)
                    state.isReloading=false

                if (onSuccess) {
                    onSuccess(e)
                }
            })
            .catch((e) => {
                state.error = e.toString()
                state.loading = false
                if(isRefresh){
                    state.isRefresh=false
                }
                uni.showToast({
                    title: '错误:' + e.toString(),
                    icon: "none",
                    duration: 2000
                })
                if (onError) {
                    onError(e.toString())
                }
            })
    }

    //加载更多模式下处理s tate.data 合并数据
    const handleLoadMoreModData=(e,isReload)=>{
        const {total,records}=e
        //第二次之合并数据 如果不是reload
        if(state.data&&!isReload){
            //合并数据
            state.data=[...state.data,...records]
            //判断是否还有数据
            const recordsLength=state.data.length
            /*
            * 为啥是大于等于呢，正常情况下等于是没问题的
            * 但是第一次查10条，一共十二条，第二次查询的时候，突然删的只剩下一条数据了，那么返回的total是不是1 是不是就比当前合并的数组少了。
            * */
            if(recordsLength>=total)
                state.isThereMore=false
        }
        //第一次直接赋值
        else{
            //如果有值
            if(total!==0)
                state.data=records
            else{
                state.data=[]
                state.isThereMore=false
            }

        }
    }


    //普通执行 会清空之前查询的数据 相当于reLoad 、
    const run = (params) => {
        if(loadMoreMod){
            state.loadingMore=false
            state.isThereMore=true
            state.isReloading=false
            tempParams=params//加载更多模式保存查询参数，给reload，和loadMore用
        }
        state.error = null//重置错误状态
        state.loading = true//加载状态改为加载中
        state.data = null//重置之前查询的数据
        //执行
        execute(params)
    }

    //局部刷新
    const reFresh=()=>{
        state.isRefresh = true//加载状态改为加载中
        //执行
        if(tempParams)
            execute(tempParams,{isRefresh: true})
        else
            execute(undefined,{isRefresh: true})
    }

    //加载更多
    const loadMore=()=>{
        //如果还要更多的数据，而且当前不是正在加载更多的状态
        if(state.isThereMore&&!state.loadingMore){
            state.loadingMore=true
            //执行
            //如果有保存的参数，则传递保存的参数
            if(tempParams)
                execute(tempParams)
            else
                execute()
        }
    }

    //重新加载
    const reload=()=>{
        state.loading=false
        state.error=null
        state.loadingMore=false
        state.isThereMore=true
        state.isReloading=true
        //执行
        if(tempParams)
            execute(tempParams,{isReload:true})
        else
            execute(undefined,{isReload:true})
    }

    //如果手动触发为false，则直接run查询
    if (!manual) run()


    state.run=run

    //加载更多模式不适用局部刷新
    if(!loadMoreMod){
        state.reFresh=reFresh
    }
    //只有加载更多模式下才有的reload 和loadMore
    if(loadMoreMod){
        state.reload=reload
        state.loadMore=loadMore
    }
    return state
}

export {
    useRequest
}
